using System;
using System.Collections.Generic;

namespace ICSharpCode.TextEditor.Document
{
    public class CSharpFoldingStrategy : IFoldingStrategy
    {
        private int GetLevel(IDocument document, int offset)
        {
            int i = 0;
            int num = 0;
            checked
            {
                for (int j = offset; j < document.TextLength; num = 0, i++, j++)
                {
                    switch (document.GetCharAt(j))
                    {
                        case ' ':
                            if (++num == 4)
                            {
                                continue;
                            }
                            break;
                        case '\t':
                            continue;
                    }
                    break;
                }
                return i;
            }
        }

        private FoldMarker FindLast(List<FoldMarker> list)
        {
            return list[checked(list.Count - 1)];
        }

        public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
        {
            return GenerateFoldMarkers(document);
        }

        public List<FoldMarker> GenerateFoldMarkers(IDocument document)
        {
            List<FoldMarker> list = new List<FoldMarker>();
            Stack<int> stack = new Stack<int>();
            Stack<string> stack2 = new Stack<string>();
            int endLine = 0;
            bool flag = false;
            bool flag2 = false;
            string text = "";
            int num = 0;
            bool flag3 = false;
            string text2 = "";
            checked
            {
                for (int i = 0; i < document.TotalNumberOfLines; i++)
                {
                    LineSegment lineSegment = document.GetLineSegment(i);
                    int textLength = document.TextLength;
                    int j;
                    for (j = lineSegment.Offset; j < textLength; j++)
                    {
                        char charAt;
                        if ((charAt = document.GetCharAt(j)) != ' ' && charAt != '\t')
                        {
                            break;
                        }
                    }
                    if (j == textLength)
                    {
                        break;
                    }
                    int num2 = j - lineSegment.Offset;
                    int num3 = 0;
                    char charAt2 = document.GetCharAt(j);
                    string text3 = document.GetText(j, lineSegment.Length - num2);
                    if (!flag && text3.Trim().StartsWith("using", StringComparison.OrdinalIgnoreCase))
                    {
                        if (!flag2)
                        {
                            stack.Push(i);
                            flag2 = true;
                            text = text3;
                        }
                        endLine = i;
                        stack2.Push(text3);
                    }
                    if (flag2 && !flag && !string.IsNullOrEmpty(text3) && !string.IsNullOrEmpty(text3.Trim()) && !text3.Trim().StartsWith("using", StringComparison.OrdinalIgnoreCase))
                    {
                        num3 = stack.Pop();
                        string text4 = stack2.Pop();
                        string text5 = "using ...";
                        list.Add(new FoldMarker(document, num3, document.GetLineSegment(num3).Length - text.Length, endLine, num2 + text.Length + text4.Length + text5.Length, FoldType.Unspecified, text5));
                        flag2 = false;
                        flag = true;
                    }
                    if (string.IsNullOrEmpty(text3))
                    {
                        continue;
                    }
                    switch (charAt2)
                    {
                        case '#':
                            if (text3.StartsWith("#region"))
                            {
                                stack.Push(i);
                                stack2.Push(text3);
                            }
                            if (text3.StartsWith("#endregion") && stack.Count > 0)
                            {
                                num3 = stack.Pop();
                                string text6 = stack2.Pop();
                                string foldText = text6.Replace("#region", "").Trim();
                                list.Add(new FoldMarker(document, num3, document.GetLineSegment(num3).Length - text6.Length, i, num2 + "#region".Length + "endregion".Length + text6.Length, FoldType.Region, foldText));
                            }
                            break;
                        case '/':
                            if (text3.StartsWith("/// <summary>") || text3.StartsWith("///<summary>"))
                            {
                                stack.Push(i);
                                text2 = "";
                                num = i;
                                flag3 = true;
                                break;
                            }
                            if (flag3 && text3.StartsWith("///") && text3.IndexOf("</summary>") == -1)
                            {
                                string text7 = "";
                                if (!string.IsNullOrEmpty(text2))
                                {
                                    text7 = " ";
                                }
                                text2 = text2 + text7 + text3.Replace("///", "").Trim();
                            }
                            if ((text3.StartsWith("/// </summary>") || text3.StartsWith("///</summary>")) && stack.Count > 0)
                            {
                                flag3 = false;
                                num3 = stack.Pop();
                                list.Add(new FoldMarker(document, num3, document.GetLineSegment(num3).Length - "/// <summary>".Length, i, num2 + "/// </summary>".Length, FoldType.TypeBody, text2));
                            }
                            if (text3.StartsWith("/// <param name="))
                            {
                                list[list.Count - 1] = new FoldMarker(document, num, document.GetLineSegment(num).Length - "/// <summary>".Length, i, num2 + 100, FoldType.TypeBody, text2);
                            }
                            if (text3.StartsWith("/// <remarks>"))
                            {
                                list[list.Count - 1] = new FoldMarker(document, num, document.GetLineSegment(num).Length - "/// <summary>".Length, i, num2 + 100, FoldType.TypeBody, text2);
                                text2 = "";
                            }
                            if (text3.StartsWith("/// <returns>"))
                            {
                                string text8 = "";
                                if (string.IsNullOrEmpty(text2))
                                {
                                    text8 = text3.Replace("///", "").Trim();
                                }
                                list[list.Count - 1] = new FoldMarker(document, num, document.GetLineSegment(num).Length - "/// <summary>".Length, i, num2 + 100, FoldType.TypeBody, text2 + text8);
                                text2 = "";
                            }
                            break;
                        case '{':
                        case '}':
                            if (text3.StartsWith("{"))
                            {
                                stack.Push(i);
                            }
                            if (text3.StartsWith("}") && stack.Count > 0)
                            {
                                num3 = stack.Pop() - 1;
                                list.Add(new FoldMarker(document, num3, document.GetLineSegment(num3).Length, i, num2 + 100, FoldType.TypeBody));
                            }
                            break;
                    }
                }
                return list;
            }
        }
    }
}
